package com.gitee.wsl.ext.reflect

import kotlin.reflect.KClass
import kotlin.reflect.KClassifier
import kotlin.reflect.KType
import kotlin.reflect.KTypeParameter
import kotlin.reflect.KVariance


fun KTypeParameter.simpleToString(): String {
    return buildList {
        if (isReified) add("reified")
        when (variance) {
            KVariance.IN -> add("in")
            KVariance.OUT -> add("out")
            KVariance.INVARIANT -> {}
        }
        if (name.isNotEmpty()) add(name)
        if (upperBounds.isNotEmpty()) {
            add(":")
            addAll(upperBounds.map { it.toString() })
        }
    }
        .joinToString(" ")
}

//private fun KClassifier.simpleToString(): String {
//    return when (this) {
//        is KClass<*> -> qualifiedNameForComparison ?: "<anonymous>"
//        is KTypeParameter -> simpleToString()
//        else -> error("Unknown type classifier: $this")
//    }
//}

//internal fun KTypeParameter.simpleToString(): String {
//    return buildList {
//        if (isReified) add("reified")
//        when (variance) {
//            KVariance.IN -> add("in")
//            KVariance.OUT -> add("out")
//            KVariance.INVARIANT -> {}
//        }
//        if (name.isNotEmpty()) add(name)
//        if (upperBounds.isNotEmpty()) {
//            add(":")
//            addAll(upperBounds.map { it.toString() })
//        }
//    }
//        .joinToString(" ")
//}

fun KClassifier.simpleToString(): String {
    return when (this) {
        is KClass<*> -> qualifiedNameForComparison ?: "<anonymous>"
        is KTypeParameter -> simpleToString()
        else -> error("Unknown type classifier: $this")
    }
}


internal class KTypeParameterImpl(
    override val isReified: Boolean,
    override val name: String,
    override val upperBounds: List<KType>,
    override val variance: KVariance,
) : KTypeParameter {
    override fun equals(other: Any?): Boolean {
        if (this === other) return true

        other as KTypeParameterImpl

        if (isReified != other.isReified) return false
        if (name != other.name) return false
        if (upperBounds != other.upperBounds) return false
        if (variance != other.variance) return false

        return true
    }

    override fun hashCode(): Int {
        var result = isReified.hashCode()
        result = 31 * result + name.hashCode()
        result = 31 * result + upperBounds.hashCode()
        result = 31 * result + variance.hashCode()
        return result
    }

    override fun toString(): String {
        return simpleToString()
    }
}
